package com.yc.testupload.dao;

import com.yc.testupload.model.User;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.yc.testupload.util.DatabaseUtil;

import java.math.BigDecimal;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.sql.*;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Date;

/**
 * 用户数据访问对象
 * 处理用户表的数据库操作
 */
public class UserDAO {
    private static final Logger logger = LogManager.getLogger(UserDAO.class);

    /**
     * 检查用户名是否已存在
     * 
     * @param username 用户名
     * @return 是否存在
     */
    public boolean checkUsernameExists(String username) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            conn = DatabaseUtil.getConnection();
            String sql = "SELECT COUNT(*) FROM wk_user WHERE user_name = ?";
            pstmt = conn.prepareStatement(sql);
            pstmt.setString(1, username);
            rs = pstmt.executeQuery();
            if (rs.next()) {
                return rs.getInt(1) > 0;
            }
        } catch (SQLException e) {
            logger.error("检查用户名是否存在时出错: {}", e.getMessage(), e);
        } finally {
            closeResources(conn, pstmt, rs);
        }
        return false;
    }

    /**
     * 检查邮箱是否已存在
     * 
     * @param email 邮箱
     * @return 是否存在
     */
    public boolean checkEmailExists(String email) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            conn = DatabaseUtil.getConnection();
            String sql = "SELECT COUNT(*) FROM wk_user WHERE user_email = ?";
            pstmt = conn.prepareStatement(sql);
            pstmt.setString(1, email);
            rs = pstmt.executeQuery();
            if (rs.next()) {
                return rs.getInt(1) > 0;
            }
        } catch (SQLException e) {
            logger.error("检查邮箱是否存在时出错: {}", e.getMessage(), e);
        } finally {
            closeResources(conn, pstmt, rs);
        }
        return false;
    }

    /**
     * 检查手机号是否已存在
     * 
     * @param phone 手机号
     * @return 是否存在
     */
    public boolean checkPhoneExists(String phone) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            conn = DatabaseUtil.getConnection();
            // 使用user_name字段存储手机号（系统设计如此）
            String sql = "SELECT COUNT(*) FROM wk_user WHERE user_name = ?";
            pstmt = conn.prepareStatement(sql);
            pstmt.setString(1, phone);
            rs = pstmt.executeQuery();
            if (rs.next()) {
                return rs.getInt(1) > 0;
            }
        } catch (SQLException e) {
            logger.error("检查手机号是否存在时出错: {}", e.getMessage(), e);
        } finally {
            closeResources(conn, pstmt, rs);
        }
        return false;
    }

    /**
     * 创建新用户
     * 
     * @param user 用户对象
     * @return 是否创建成功
     */
    public boolean createUser(User user) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        try {
            conn = DatabaseUtil.getConnection();
            String sql = "INSERT INTO wk_user (user_name, user_email, user_pass, user_salt, user_avatar, user_reg_time, user_money) VALUES (?, ?, ?, ?, ?, ?, ?)";
            pstmt = conn.prepareStatement(sql);
            pstmt.setString(1, user.getUserName());
            pstmt.setString(2, user.getUserEmail());
            pstmt.setString(3, user.getUserPass());
            pstmt.setString(4, user.getUserSalt());
            pstmt.setString(5, "/assets/index/images/head.png"); // 默认头像

            // 注意：数据库中user_reg_time字段是int(10)类型，需要存储毫秒时间戳的整数值
            pstmt.setLong(6, System.currentTimeMillis() / 1000); // 存储Unix时间戳（秒）
            pstmt.setBigDecimal(7, new BigDecimal(0)); // 初始余额为0

            int rowsAffected = pstmt.executeUpdate();
            return rowsAffected > 0;
        } catch (SQLException e) {
            logger.error("创建用户时出错: {}", e.getMessage(), e);
        } finally {
            closeResources(conn, pstmt, null);
        }
        return false;
    }

    /**
     * 根据用户名获取用户ID
     * 
     * @param username 用户名
     * @return 用户对象（只包含user_id和user_name）
     */
    public User getUserByUsername(String username) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            conn = DatabaseUtil.getConnection();
            String sql = "SELECT user_id, user_name FROM wk_user WHERE user_name = ?";
            pstmt = conn.prepareStatement(sql);
            pstmt.setString(1, username);
            rs = pstmt.executeQuery();
            if (rs.next()) {
                User user = new User();
                user.setUserId(rs.getInt("user_id"));
                user.setUserName(rs.getString("user_name"));
                return user;
            }
        } catch (SQLException e) {
            logger.error("根据用户名查询用户ID时出错: {}", e.getMessage(), e);
        } finally {
            closeResources(conn, pstmt, rs);
        }
        return null;
    }

    /**
     * 根据用户名和密码查询用户
     * 
     * @param username 用户名
     * @param password 密码
     * @return 用户对象
     */
    public User getUserByUsernameAndPassword(String username, String password) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            conn = DatabaseUtil.getConnection();
            String sql = "SELECT * FROM wk_user WHERE user_name = ?";
            pstmt = conn.prepareStatement(sql);
            pstmt.setString(1, username);
            rs = pstmt.executeQuery();
            if (rs.next()) {
                String storedHash = rs.getString("user_pass");
                String salt = rs.getString("user_salt");

                // 验证密码
                if (verifyPassword(password, salt, storedHash)) {
                    User user = new User();
                    user.setUserId(rs.getInt("user_id"));
                    user.setUserName(rs.getString("user_name"));
                    user.setUserEmail(rs.getString("user_email"));
                    user.setUserPass(storedHash);
                    user.setUserSalt(salt);
                    user.setWeixinOpenId(rs.getString("weixin_open_id"));
                    user.setUserMoney(rs.getBigDecimal("user_money"));
                    user.setUserAvatar(rs.getString("user_avatar"));
                    // 注意：数据库中user_reg_time字段是int(10)类型的Unix时间戳（秒）
                    // 需要先获取整数值，然后转换为Date对象
                    long regTimeSeconds = rs.getLong("user_reg_time");
                    user.setUserRegTime(new Date(regTimeSeconds * 1000)); // 转换为毫秒时间戳
                    user.setUserVipWenIncome(rs.getBigDecimal("user_vip_wen_income"));
                    user.setUserPayWenIncome(rs.getBigDecimal("user_pay_wen_income"));
                    user.setVipLevelId(rs.getInt("vip_level_id"));
                    // 对于vip_end_time也需要进行相同的处理
                    if (rs.getObject("vip_end_time") != null) {
                        long vipEndTimeSeconds = rs.getLong("vip_end_time");
                        user.setVipEndTime(new Date(vipEndTimeSeconds * 1000)); // 转换为毫秒时间戳
                    }
                    user.setVipDownFee(rs.getBigDecimal("vip_down_fee"));
                    user.setWenStatus(rs.getInt("wen_status"));
                    // 数据库中不存在lineuid列，已注释
                    user.setInviteUserid(rs.getInt("invite_userid"));
                    return user;
                }
            }
        } catch (SQLException e) {
            logger.error("根据用户名和密码查询用户时出错: {}", e.getMessage(), e);
        } finally {
            closeResources(conn, pstmt, rs);
        }
        return null;
    }

    /**
     * 生成随机盐值
     * 
     * @return 盐值
     */
    public String generateSalt() {
        SecureRandom random = new SecureRandom();
        byte[] salt = new byte[16];
        random.nextBytes(salt);
        return Base64.getEncoder().encodeToString(salt);
    }

    /**
     * 加密密码
     * 
     * @param password 原始密码
     * @param salt     盐值
     * @return 加密后的密码
     */
    public String hashPassword(String password, String salt) {
        try {
            // 使用MD5算法，将密码与盐值直接拼接
            String passwordWithSalt = password + salt;
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] hashedPassword = md.digest(passwordWithSalt.getBytes());

            // 将字节数组转换为十六进制字符串
            StringBuilder sb = new StringBuilder();
            for (byte b : hashedPassword) {
                sb.append(String.format("%02x", b));
            }
            return sb.toString();
        } catch (NoSuchAlgorithmException e) {
            logger.error("加密密码时出错: {}", e.getMessage(), e);
            throw new RuntimeException("密码加密失败", e);
        }
    }

    /**
     * 验证密码
     * 
     * @param inputPassword 输入的密码
     * @param salt          盐值
     * @param storedHash    存储的哈希值
     * @return 是否验证通过
     */
    private boolean verifyPassword(String inputPassword, String salt, String storedHash) {
        String hashedInput = hashPassword(inputPassword, salt);
        return hashedInput.equals(storedHash);
    }

    /**
     * 关闭数据库资源
     * 
     * @param conn  连接
     * @param pstmt 预编译语句
     * @param rs    结果集
     */
    private void closeResources(Connection conn, PreparedStatement pstmt, ResultSet rs) {
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                logger.error("关闭ResultSet时出错: {}", e.getMessage(), e);
            }
        }
        if (pstmt != null) {
            try {
                pstmt.close();
            } catch (SQLException e) {
                logger.error("关闭PreparedStatement时出错: {}", e.getMessage(), e);
            }
        }
        if (conn != null) {
            DatabaseUtil.closeConnection(conn);
        }
    }
}